home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr11 / ddj9304.zip / WAVELET.ZIP / V592X480.C < prev    next >
Text File  |  1992-05-17  |  13KB  |  456 lines

  1. /* V592X480.C */
  2.  
  3. /* Mode set routine for VGA 592x480 16-color mode.
  4.      Tested with Borland C 2.0 */
  5. #include <stdlib.h>
  6. #include <dos.h>
  7. #include "V592x480.h"
  8.  
  9. unsigned ROMsetSEG, ROMsetOFF;
  10. unsigned far *ROMset;
  11. unsigned char far *ROMptr;
  12. unsigned char palette_set[17] = {0, 1, 60, 3, 4, 5, 6, 55,
  13.                                                                  1, 62, 1, 62, 56, 62, 7, 62, 0};
  14.  
  15. void Set592x480(void)
  16. {
  17.     union REGS regset;
  18.     struct SREGS sregset;
  19.  
  20.     /* First, set to standard 640x480 mode (mode 12h) */
  21.     regset.x.ax = 0x0012;
  22.     int86(0x10, ®set, ®set);
  23.  
  24.     /* Obtain location of 8x8 pixel character set */
  25.     ROMset = (unsigned far *) MK_FP(0x0, 0x10c);
  26.     regset.x.ax = 0x1123;
  27.     regset.h.bl = 0x03;
  28.     int86(0x10, ®set, ®set);
  29.     ROMsetOFF = ROMset[0];
  30.     ROMsetSEG = ROMset[1];
  31.     ROMptr = (unsigned char far *) MK_FP(ROMsetSEG, ROMsetOFF);
  32.  
  33.     /* Next, set up the new color palette */
  34.     regset.x.ax = 0x1002;
  35.     regset.x.dx = (unsigned int) palette_set;
  36.     sregset.es = _DS;
  37.     int86x(0x10, ®set, ®set, &sregset);
  38.  
  39.     /* Now, tweak the registers needed to convert the horizontal character
  40.          count from 80 to 74 characters (640 to 592 pixels) per line */
  41.     outportb(0x3D4, 0x11); /* allow access to CRTC registers 0 - 7 */
  42.     outportb(0x3D5, inportb(0x3D5) & 0x7f);
  43.     outport(0x3D4, 0x4901);  /* adjust the Horizontal Display Enable End
  44.                                                             register for 74 byte display area width */
  45.     outport(0x3D4, 0x2513);  /* adjust the Offset register for 74 byte
  46.                                                             (37 word) display area width */
  47.     /* adjust the Line Compare register to start display of
  48.          non-flipping area at line 400 (row scan number 399 (0x18f) */
  49.     outportb(0x3D4, 9); /* clear tenth bit of Line Compare count */
  50.     outportb(0x3D5, inportb(0x3D5) & 0xbf);
  51.     outportb(0x3D4, 7); /* set ninth bit of Line Compare count */
  52.     outportb(0x3D5, inportb(0x3D5) | 0x10);
  53.     outport(0x3D4, 0x8f18); /* remaining eight bits of Line Compare */
  54.  
  55.     /* adjust the Start Address High and Start Address Low registers
  56.          to start screen display on page 0 */
  57.     outport(0x3D4, 0x170c);
  58.     outport(0x3D4, 0x200d);
  59.  
  60.     outportb(0x3D4, 0x11); /* block access to CRTC registers 0 - 7 */
  61.     outportb(0x3D5, inportb(0x3D5) | 0x80);
  62. }
  63.  
  64.  
  65. void DrawObject(int page, int A[][5])
  66. {
  67.     int i;
  68.  
  69.     /* draw each rectangle in list until 'null' rectangle is encountered */
  70.     for(i = 0; A[i][0] >= 0; i++)
  71.         ColorRectangle(page, A[i][0], A[i][1], A[i][2], A[i][3], A[i][4]);
  72. }
  73.  
  74.  
  75. void DrawGraph(int left, int top, int right, int bot,double *data,
  76.                                     double magnitude, int length, int color, int barsize)
  77. {
  78.     double range, scale;
  79.     int i, j, index, width, center, offset, last_offset, Ltop, Lbot;
  80.  
  81.     j = barsize - 1;
  82.     width = right - left - 1;
  83.     center = (bot + top) / 2;
  84.     range = 0.95 * (double) ((bot - top - 1) / 2);
  85.     scale = range / magnitude;
  86.     /* limit length of data to fit within bounds of the graph */
  87.     if ((length * barsize) > width)
  88.         length = width / barsize;
  89.  
  90.     last_offset = 0;
  91.     for(i = 0, index = left + 1; i < length; index += barsize, i++)
  92.     {  /* draw the bars of the graph */
  93.         offset = (int) (data[i] * scale);
  94.         if (offset > last_offset) /* properly format excursion in Y direction */
  95.         {
  96.             Ltop = center - offset;
  97.             Lbot = center - last_offset;
  98.         }
  99.         else if (offset < last_offset)
  100.         {
  101.             Ltop = center - last_offset;
  102.             Lbot = center - offset;
  103.         }
  104.         else
  105.         {
  106.             Ltop = center - offset;
  107.             Lbot = center - offset;
  108.         }
  109.         ColorRectangle(STATIC_PAGE, index, Ltop, index + j, Lbot, color);
  110.         last_offset = offset;
  111.     }
  112. }
  113.  
  114.  
  115. #define CLD                0xfc
  116. #define PUSH_DS        0x1e
  117. #define PUSH_CX        0x51
  118. #define POP_DS        0x1f
  119. #define POP_CX        0x59
  120. #define REP                0xf3
  121. #define MOVSB         0xa4
  122. #define STOSB       0xaa
  123. #define INSW            0x6d
  124. #define DEC_AX        0X48
  125. #define DEC_BX    0x4b
  126. #define DEC_CX        0X49
  127. #define DEC_DX        0X4a
  128. #define INC_DX        0X42
  129. #define DEC_SI        0X4e
  130. #define JNE                0X75
  131. #define OUTSB            0x6e
  132. #define OUT_DX_AL 0xee
  133. #define USE_ES        0x26
  134. #define MOV_AL_DI 0x058a
  135. #define MOV_CX_AX 0xc88b
  136. #define MOV_CX_DX    0xca8b
  137. #define MOV_DI_CL 0x0d88
  138. #define ADD_DI_BX 0xfb03
  139. #define ADD_SI_BX    0xf303
  140. #define ADD_SI_CX    0xf103
  141. #define SUB_SI_CX    0xf12b
  142.  
  143.  
  144. int DrawChar(int page, int row, int col, int color, int c)
  145. {
  146.     int maxrow;
  147.     unsigned page_base;
  148.  
  149.     /* determine location of page on which to draw the character */
  150.     switch (page)
  151.     {
  152.         case PAGE_0:
  153.             page_base = 0x1720;
  154.             maxrow = 400;
  155.             break;
  156.         case PAGE_1:
  157.             page_base = 0x8b20;
  158.             maxrow = 400;
  159.             break;
  160.         case STATIC_PAGE:
  161.             page_base = 0x0;
  162.             maxrow = 80;
  163.     }
  164.  
  165.     /* abort attempt to draw outside page boundaries */
  166.     if ((row >= maxrow) || (col >= 74))
  167.         return -1;
  168.  
  169.     /* set the Mode Register Write Mode to 2 */
  170.     outportb(0x3ce, 5);  outportb(0x3cf, (inportb(0x3cf) & 0xfc) | 0x02);
  171.  
  172.     /* point to the Bit Mask Register */
  173.     outportb(0x3ce, 8);
  174.  
  175.     _DI = page_base + (row * 74) + col;
  176.     _SI = ROMsetOFF + (c << 3);
  177.     _ES = 0xa000;
  178.     _CL = color;
  179.     _BX = 8;
  180.     _DX = 0x03cf; /* set up port address for Bit Mask Register */
  181.     __emit__(PUSH_DS);
  182.     _DS = ROMsetSEG;
  183.  
  184.     __emit__(OUTSB, USE_ES, MOV_AL_DI, USE_ES, MOV_DI_CL);
  185.     _DI += 74;
  186.     __emit__(DEC_BX, JNE, 0xef, POP_DS);
  187.  
  188.     /* enable all bits in Bit Mask Register */
  189.     outportb(0x3cf, 0xff);
  190.     /* set the Mode Register Write Mode to 0 */
  191.     outportb(0x3ce, 5);  outportb(0x3cf, inportb(0x3cf) & 0xfc);
  192.     return(c);
  193. }
  194.  
  195.  
  196. int DrawString(int page, int row, int col, int color, char *c)
  197. {
  198.     int maxrow, j;
  199.     unsigned page_base;
  200.     char ch;
  201.  
  202.     /* set the Mode Register Write Mode to 2 */
  203.     outportb(0x3ce, 5);  outportb(0x3cf, (inportb(0x3cf) & 0xfc) | 0x02);
  204.  
  205.     /* point to the Bit Mask Register */
  206.     outportb(0x3ce, 8);
  207.  
  208.     /* determine location of page on which to draw the character */
  209.     switch(page)
  210.     {
  211.         case PAGE_0:
  212.             page_base = 0x1720;
  213.             maxrow = 400;
  214.             break;
  215.         case PAGE_1:
  216.             page_base = 0x8b20;
  217.             maxrow = 400;
  218.             break;
  219.         case STATIC_PAGE:
  220.             page_base = 0x0;
  221.             maxrow = 80;
  222.     }
  223.  
  224.     /* abort attempt to draw outside page boundary */
  225.     if (row >= maxrow)
  226.         return -1;
  227.  
  228.     _ES = 0xa000;
  229.     _DI = page_base + (row * 74) + col;
  230.     _CL = color;
  231.     j = 0;
  232.     while ((ch = c[j++]) != '\0')
  233.     {
  234.         _SI = ROMsetOFF + (ch << 3);
  235.         _BX = 8;
  236.         _DX = 0x03cf; /* set up port address for Bit Mask Register */
  237.         __emit__(PUSH_DS);
  238.         _DS = ROMsetSEG;
  239.  
  240.         __emit__(OUTSB, USE_ES, MOV_AL_DI, USE_ES, MOV_DI_CL);
  241.         _DI += 74;
  242.         __emit__(DEC_BX, JNE, 0xef, POP_DS);
  243.  
  244.         _DI -= 591;
  245.     }
  246.  
  247.     /* enable all bits in Bit Mask Register */
  248.     outportb(0x3cf, 0xff);
  249.     /* set the Mode Register Write Mode to 0 */
  250.     outportb(0x3ce, 5);  outportb(0x3cf, inportb(0x3cf) & 0xfc);
  251.     return(0);
  252. }
  253.  
  254.  
  255. unsigned char colorarray[74];
  256. unsigned char leftedges[8] = {0xff, 0x7f, 0x3f, 0x1f,
  257.                                                             0x0f, 0x07, 0x03, 0x01};
  258. unsigned char rightedges[8] = { 0x80, 0xc0, 0xe0, 0xf0,
  259.                                                                 0xf8, 0xfc, 0xfe, 0xff };
  260.  
  261. void ColorRectangle(int page, int left, int top, int right, int bot, int color)
  262. {
  263.     int i, temp, vmax;
  264.     int leftedgebyte, rightedgebyte;
  265.     unsigned int leftedgesize, rightedgesize;
  266.     unsigned int byteblocksize, wrapblocksize;
  267.     unsigned char leftedgeblock, rightedgeblock;
  268.  
  269.     /* limit horizontal range to page size */
  270.     left = max(0, left);  left = min(591, left);
  271.     right = max(0, right);  right = min(591, right);
  272.  
  273.     /* correct accending order of horizontal coordinates */
  274.     if (right < left)
  275.     {
  276.         temp = left; left = right; right = temp;
  277.     }
  278.  
  279.     if (page == STATIC_PAGE) /* static page does not filp - size is 591 x 80 */
  280.         vmax = 79;
  281.     else
  282.         vmax = 399; /* pages 0 and 1 filp - size is 591 x 400 */
  283.  
  284.     /* limit vertical range to page size */
  285.     top = max(0, top);  top = min(vmax, top);
  286.     bot = max(0, bot);  bot = min(vmax, bot);
  287.  
  288.     /* correct accending order of vertical coordinates */
  289.     if (bot < top)
  290.     {
  291.         temp = top; top = bot; bot = temp;
  292.     }
  293.  
  294.     /* calculate byte position of left and right edges */
  295.     leftedgebyte = left / 8;  rightedgebyte = right / 8;
  296.  
  297.     /* calculate bit position of left and right edges */
  298.     leftedgesize = left - leftedgebyte * 8;
  299.     rightedgesize = right - rightedgebyte * 8;
  300.  
  301.     /* calculate integral byte width of rectangle and
  302.          wrap around index for drawing routine */
  303.     byteblocksize = rightedgebyte - leftedgebyte + 1;
  304.     wrapblocksize = 74 - byteblocksize;
  305.  
  306.     /* get pixel maps of left and right edges */
  307.     leftedgeblock = leftedges[leftedgesize];
  308.     rightedgeblock = rightedges[rightedgesize];
  309.  
  310.     /* combine pixel maps if left and right edges are on the same byte */
  311.     if (leftedgebyte == rightedgebyte)
  312.         leftedgeblock &= rightedgeblock;
  313.  
  314.     /* set up color for the rectangle */
  315.     for (i = 0; i < byteblocksize; i++)
  316.         colorarray[i] = color;
  317.  
  318.     /* set the Mode Register Write Mode to 2 */
  319.     outportb(0x3ce, 5);  outportb(0x3cf, (inportb(0x3cf) & 0xfc) | 0x02);
  320.  
  321.     /* point to the Bit Mask Register */
  322.     outportb(0x3ce, 8);
  323.  
  324.     __emit__(CLD); /* assure that MOVSB increments SI and DI */
  325.  
  326.     if (page == 0)  /* set up starting address of selected page */
  327.         _DI = 0x1720;
  328.     else if (page == 1)
  329.         _DI = 0x8b20;
  330.     else
  331.         _DI = 0x0000;
  332.  
  333.     /* adjust start to upper lefthand corner of the rectangle */
  334.     _DI += leftedgebyte + top * 74;
  335.     _ES = 0xa000; /* set segment for screen memory */
  336.     _DX = 0x03cf; /* set up port address for Bit Mask Register */
  337.  
  338.     for (i = 0; i < bot - top + 1; i++)
  339.     {
  340.         _SI = (unsigned int) colorarray;
  341.         _AL = leftedgeblock;
  342.  
  343.         /* current pixels in byte of left edge need to be preserved
  344.              by reading the memory location location first */
  345.         __emit__(OUT_DX_AL, USE_ES, MOV_AL_DI, MOVSB);
  346.  
  347.         if (byteblocksize > 1) /* more than one byte wide */
  348.         {
  349.             if (byteblocksize > 2) /* more than two bytes wide */
  350.             {
  351.                 _CX = byteblocksize - 2;
  352.                 /* all pixels in byte are over-written in body of rectangle,
  353.                      so no pixels need to be preserved; speeds up drawing! */
  354.                 _AL = 0xff;
  355.                 __emit__(OUT_DX_AL, REP, MOVSB);
  356.             }
  357.  
  358.             _AL = rightedgeblock;
  359.  
  360.         /* current pixels in byte of right edge need to be preserved
  361.              by reading the memory location location first */
  362.             __emit__(OUT_DX_AL, USE_ES, MOV_AL_DI, MOVSB);
  363.         }
  364.  
  365.         _DI += wrapblocksize;
  366.     }
  367.  
  368.     /* enable all bits in Bit Mask Register */
  369.     outportb(0x3cf, 0xff);
  370.     /* set the Mode Register Write Mode to 0 */
  371.     outportb(0x3ce, 5);  outportb(0x3cf, inportb(0x3cf) & 0xfc);
  372. }
  373.  
  374.  
  375. static unsigned int shift_blocks[7][2]
  376.     = { {42, 32}, {26, 48}, {18, 56},
  377.             {14, 60}, {12, 62}, {11, 63}, {11, 63}};
  378.  
  379. void ShiftWaveTraces(unsigned int src, unsigned int dest)
  380. {
  381.     int i;
  382.  
  383.     /* set the Mode Register Write Mode to 1 */
  384.     outportb(0x3ce, 5);
  385.     outportb(0x3cf, (inportb(0x3cf) & 0xfc) | 0x01);
  386.  
  387.     /* set the Map Mask Register to enable writes to pixel planes
  388.          0, 1, and 3 and disable writes to pixel plane 2 */
  389.     outport(0x3c4, 0x0b02);
  390.  
  391.     _SI = src;
  392.     _DI = dest + 10;
  393.     _ES = 0xa000;
  394.     __emit__(CLD); /* assure that MOVSB increments SI and DI */
  395.  
  396.     for (i = 0; i < 7; i++)
  397.     {
  398.         _DX = shift_blocks[i][1]; /* load the length of each line for block */
  399.         _BX = shift_blocks[i][0]; /* init middle loop for wrap value for block */
  400.  
  401.         __emit__(PUSH_DS);
  402.  
  403.         _DS = 0xa000;
  404.         _AX = 50;          /* init middle loop for number of lines in block */
  405.  
  406.         __emit__(ADD_SI_BX, MOV_CX_DX, REP, MOVSB);
  407.         __emit__(ADD_DI_BX, DEC_AX, JNE, 0xf5, POP_DS);
  408.     }
  409.  
  410.     /* set the Mode Register Write Mode to 0 */
  411.     outportb(0x3ce, 5);
  412.     outportb(0x3cf, inportb(0x3cf) & 0xfc);
  413.  
  414.     /* set the Map Mask Register to enable writes to all pixel planes */
  415.     outport(0x3c4, 0x0f02);
  416. }
  417.  
  418.  
  419. static unsigned int imag_blocks[6][2]
  420.     = { {10, 32}, {42, 16}, {58, 8}, {66, 4}, {70, 2}, {72, 1} };
  421.  
  422. void GetDSPimage(unsigned int dest, unsigned io_addr)
  423. {
  424.     int i;
  425.  
  426.     /* Map Mask register - set pixel planes 1, 2, and 3 to "0",
  427.          pixel plane 0 to "1" */
  428.     outport(0x3c4, 0x0102);
  429.  
  430.     _DX = io_addr;
  431.     _DI = dest;
  432.     _ES = 0xa000;
  433.  
  434.     __emit__(CLD); /* assure that INSW increments DI */
  435.  
  436.     for (i = 0; i < 6; i++)
  437.     {
  438.         /* point to fill element offset */
  439.         _AX = imag_blocks[i][1]; /* load the length of each line for block */
  440.         _BX = imag_blocks[i][0]; /* init middle loop for wrap value for block */
  441.         _SI = 50;       /* init middle loop for number of lines in image block */
  442.  
  443.         __emit__(ADD_DI_BX); /* wrap destination pointer to next row of display */
  444.         __emit__(MOV_CX_AX, REP, INSW, DEC_SI, JNE, 0xf7);
  445.     }
  446.  
  447.     _DI += 1;                /* offset pointer by one */
  448.     _CX = imag_blocks[5][0]; /* init middle loop for wrap value for block */
  449.     _SI = 100;        /* init middle loop for number of lines in image block */
  450.  
  451.     __emit__(ADD_DI_BX, INSW, DEC_SI, JNE, 0xfa);
  452.  
  453.     /* Map Mask register - set pixel planes 0 - 3 to "1" */
  454.     outport(0x3c4, 0x0f02);
  455. }
  456.